using System;
using System.Collections.Generic;
using System.Globalization;
using Medianamik.Core;
using Medianamik.Core.DAL;
using Medianamik.Tests.Unit.Fakes;
using Moq;
using NUnit.Framework;

namespace Medianamik.Tests.Unit.Medianamik.Core
{
    [TestFixture]
    public class NodePropertyTest
    {
        private Guid _nodeTypeId;
        [SetUp]
        public void Init()
        {
            _nodeTypeId = Guid.NewGuid();
        }

        [Test]
        public void When_no_ID_is_passed_in_constructor_IsNew_should_be_true()
        {
            var prop1 = new NodeProperty(default(int?), default(NodeTypeProperty), default(object), "",
                                         default(int?), new Node());
            var prop2 = new NodeProperty(default(NodeTypeProperty), default(object), "", new Node());
            Assert.That(prop1.IsNew, Is.True);
            Assert.That(prop2.IsNew, Is.True);
        }

        [Test]
        public void When_passing_an_Id_in_constructor_IsNew_should_be_false()
        {
            var prop1 = new NodeProperty(1, default(NodeTypeProperty), default(object), "",
                                         default(int?), new Node());
            Assert.That(prop1.IsNew, Is.False);
        }

        [Test]
        public void When_creating_a_NodeProperty_it_should_not_be_Dirty()
        {
            var prop1 = new NodeProperty(default(int?), default(NodeTypeProperty), default(object), "",
                                         default(int?), new Node());
            var prop2 = new NodeProperty(default(NodeTypeProperty), default(object), "", new Node());
            Assert.That(prop1.IsDirty, Is.False);
            Assert.That(prop2.IsDirty, Is.False);
        }

        [Test]
        [Ignore]
        public void When_Value_is_changed_NodeProperty_should_be_Dirty()
        {
            var initialValue = "elephant";
            var newValue = "monkey";
            var prop = new NodeProperty(default(int?), default(NodeTypeProperty), initialValue, "",
                                        default(int?), new Node());

            prop.SetValue(initialValue);
            Assert.That(prop.IsDirty, Is.False);

            prop.SetValue(newValue);
            Assert.That(prop.IsDirty, Is.True);

        }

        [Test]
        public void NodeProperty_should_create_controls_with_same_IsLanguageNeutral_property_value()
        {
            CreateNodeTypes(_nodeTypeId);
            var invariantCultureNodeProperty = GetNodeProperty(CultureInfo.InvariantCulture.Name);

            var invariantCultureControl = (FakeMedianamikControl)invariantCultureNodeProperty.GetMedianamikControl(false, false, "", false, "", "", "", false);
            invariantCultureControl.TriggerInit();

            Assert.That(invariantCultureControl.IsLanguageNeutral, Is.True);

            var frenchNodeProperty = GetNodeProperty("fr-CA");
            var frenchControl = (FakeMedianamikControl)frenchNodeProperty.GetMedianamikControl(false, false, "", false, "", "", "", false);
            frenchControl.TriggerInit();

            Assert.That(frenchControl.IsLanguageNeutral, Is.False);

        }


        private NodeProperty GetNodeProperty(string cultureName)
        {
            bool isLanguageNeutral = cultureName == CultureInfo.InvariantCulture.Name;

            var nodeTypeProperty = new NodeTypeProperty("testProp", 0, 0, Guid.NewGuid(), false, isLanguageNeutral, false, false, null,
                                                        string.Empty, Guid.NewGuid(), default(MedianamikControlInfo), Guid.NewGuid(), 0);

            var dataType = new DataType(Guid.NewGuid(), string.Empty, false, false);
            var medianamikControl = new MedianamikControl(Guid.NewGuid(), "Medianamik.Tests.Unit.Fakes.FakeMedianamikControl, Medianamik.Tests.Unit", dataType);
            nodeTypeProperty.MedianamikControl = medianamikControl;

            var node = new NodeStub(Guid.NewGuid(), _nodeTypeId, null);
            node.Name = "Node Name";

            return new NodeProperty(nodeTypeProperty, "value", cultureName, node);
        }

        private void CreateNodeTypes(params Guid[] ids)
        {
            var nodeTypeList = new List<NodeType>();
            foreach (var id in ids)
            {
                var nodeType = new NodeType(id) { Name = "NodeType Name" };
                nodeTypeList.Add(nodeType);
            }

            var dalProviderMock = new Mock<INodeTypeDALProvider>();
            dalProviderMock.Setup(x => x.GetAllTypes(true)).Returns(nodeTypeList);
            NodeTypeManager.Provider = new NodeTypeProvider(dalProviderMock.Object);
        }

        private class NodeStub : Node
        {
            public NodeStub(Guid id, Guid nodeTypeId, Guid? parentId)
                : base(id, nodeTypeId, parentId, null, null, false)
            {
            }

            public override string Name
            {
                get;
                set;
            }
        }

    }
}